﻿using AutoMapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.DomainObject.User;
using WMS.FC.Domain.Repository;
using WMS.FC.Domain.Service.System;
using WMS.FC.Domain.Service.User.Interface;

namespace WMS.FC.Domain.Service.User
{
    public class CheckUserLoginService : ServiceBase, ICheckUserLoginService
    {
        protected readonly IUserRepository userRepository;

        public CheckUserLoginService(
            ILogger<ServiceBase> logger,
            IOptions<WmsSettings> options,
            IMapper mapper,
            IUserRepository userRepository)
            : base(logger, options, mapper)
        {
            this.userRepository = userRepository;
        }

        public async Task<ActionResult<UserDO>> CheckUserLogin(string userAccount, string password, UserInfo userInfo)
        {
            var result = new ActionResult<UserDO>("校验用户登录");

            try
            {
                if (string.IsNullOrWhiteSpace(userAccount))
                    return result.ArgumentError("用户名不能为空");

                if (string.IsNullOrWhiteSpace(password))
                    return result.ArgumentError("密码不能为空");

                var count = 0;

                var userPO = await userRepository.GetUserByAccount(userAccount);
                if (userPO == null)
                    return result.BusinessError($"用户名:{userAccount},不存在");

                if (userPO.IsLocked)
                    return result.BusinessError($"账户已锁定");

                var userDO = mapper.Map<UserDO>(userPO);
                if (userDO.Password != password)
                {
                    count = await userRepository.AddLoginError(userPO);
                    if (count == 0)
                        return result.DbError("更新用户密码错误次数异常");

                    return result.BusinessError($"密码错误,剩余重试次数:{6 - userPO.LoginErrorCount}");
                }

                userPO.LoginIp = userInfo.UserIp;
                count = await userRepository.ResetLoginFail(userPO);
                if (count == 0)
                    return result.DbError("重置登陆失败异常");

                result.Data = userDO;
            }
            catch (Exception ex)
            {
                return result.Exception(ex);
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userAccount"></param>
        /// <param name="password"></param>
        /// <param name="newPassword"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public async Task<ActionResult<string>> ChangePassword(string userAccount, string password, string newPassword, UserInfo userInfo)
        {
            var result = new ActionResult<string>("修改用户密码");
            try
            {
                if (string.IsNullOrWhiteSpace(userAccount))
                    return result.ArgumentError("用户名不能为空");

                if (string.IsNullOrWhiteSpace(password))
                    return result.ArgumentError("旧密码不能为空");

                if (string.IsNullOrWhiteSpace(newPassword))
                    return result.ArgumentError("新密码不能为空");

                var userPO = await userRepository.GetUserByAccount(userAccount);
                if (userPO == null)
                    return result.BusinessError($"用户名:{userAccount},不存在");

                //var count = 0;
                var userDO = mapper.Map<UserDO>(userPO);
                if (userDO.Password != password)
                {
                    return result.BusinessError($"旧密码错误，请重试！");
                }
                //修改记录
                userPO.Password = newPassword;
                userPO.LoginIp = userInfo.UserIp;
                userPO.ModifyDate= DateTime.Now;

                var count = await userRepository.ChangePassword(userPO);
                if (count == 0)
                    return result.DbError("重置登陆失败异常");

                result.Message = "修改密码成功。";
            }
            catch (Exception ex)
            {
                return result.Exception(ex);
            }

            return result;
        }
    }
}
